﻿using System;
using System.Collections.Generic;
using System.Composition.Convention;
using System.Reflection;

namespace Ant.Interface.Mef.Controller
{
    /// <summary>
    /// 插件控制器接口。
    /// </summary>
    public interface IMefController : IDisposable
    {
        #region "Load"

        /// <summary>
        /// 加载插件配置。
        /// </summary>
        /// <param name="configFilePath">配置文件路径。</param>
        void LoadParts(string configFilePath);

        /// <summary>
        /// 加载目录配置。
        /// </summary>
        /// <param name="configFilePath">配置文件路径。</param>
        void LoadCatalogs(string configFilePath);

        /// <summary>
        /// 加载插件映射。
        /// </summary>
        /// <param name="configFilePath">配置文件路径。</param>
        void LoadMappings(string configFilePath);

        /// <summary>

        /// 加载部件集。
        /// </summary>
        /// <param name="assembly">程序集。</param>
        void LoadParts(Assembly assembly);

        /// <summary>
        /// 加载部件集。
        /// </summary>
        /// <param name="assemblies">程序集集合。</param>
        void LoadParts(IEnumerable<Assembly> assemblies);

        /// <summary>
        /// 加载部件。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        void LoadPart(Type partType);

        /// <summary>
        /// 加载部件。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <param name="conventions">公约。</param>
        void LoadPart(Type partType, AttributedModelProvider conventions);

        /// <summary>
        /// 加载部件。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        void LoadPart<T>() where T : IDependency;

        /// <summary>
        /// 加载部件。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <param name="conventions">公约。</param>
        void LoadPart<T>(AttributedModelProvider conventions) where T : IDependency;

        /// <summary>
        /// 加载部件集。
        /// </summary>
        /// <param name="partTypes">部件类型集合。</param>
        void LoadParts(IEnumerable<Type> partTypes);

        /// <summary>
        /// 加载部件集。
        /// </summary>
        /// <param name="partTypes">部件类型集合。</param>
        /// <param name="conventions">公约。</param>
        void LoadParts(IEnumerable<Type> partTypes, AttributedModelProvider conventions);

        /// <summary>
        /// 加载部件集。
        /// </summary>
        /// <param name="partTypes">部件类型集合。</param>
        void LoadParts(params Type[] partTypes);

        #endregion "Load"

        #region "Get"

        /// <summary>
        /// 获取插件。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <returns>匹配的插件。</returns>
        T Get<T>() where T : IDependency;

        /// <summary>
        /// 获取插件。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <param name="contractName">契约名称。</param>
        /// <returns>匹配的插件。</returns>
        T Get<T>(string contractName) where T : IDependency;

        /// <summary>
        /// 获取插件。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <returns>匹配的插件。</returns>
        object Get(Type partType);

        /// <summary>
        /// 获取插件。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <param name="contractName">契约名称。</param>
        /// <returns>匹配的插件。</returns>
        object Get(Type partType, string contractName);

        /// <summary>
        /// 获取插件集合。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <returns>匹配的插件集合。</returns>
        IEnumerable<T> Gets<T>() where T : IDependency;

        /// <summary>
        /// 获取插件集合。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <param name="contractName">契约名称。</param>
        /// <returns>匹配的插件集合。</returns>
        IEnumerable<T> Gets<T>(string contractName) where T : IDependency;

        /// <summary>
        /// 获取插件集合。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <returns>匹配的插件集合。</returns>
        IEnumerable<object> Gets(Type partType);

        /// <summary>
        /// 获取插件集合。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <param name="contractName">契约名称。</param>
        /// <returns>匹配的插件集合。</returns>
        IEnumerable<object> Gets(Type partType, string contractName);

        /// <summary>
        /// 尝试获取插件。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <param name="part">匹配的插件。</param>
        /// <returns>是否成功获取。</returns>
        bool TryGet<T>(out T part) where T : IDependency;

        /// <summary>
        /// 尝试获取插件。
        /// </summary>
        /// <typeparam name="T">部件类型。</typeparam>
        /// <param name="contractName">契约名称。</param>
        /// <param name="part">匹配的插件。</param>
        /// <returns>是否成功获取。</returns>
        bool TryGet<T>(string contractName, out T part) where T : IDependency;

        /// <summary>
        /// 尝试获取插件。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <param name="part">匹配的插件。</param>
        /// <returns>是否成功获取。</returns>
        bool TryGet(Type partType, out object part);

        /// <summary>
        /// 尝试获取插件。
        /// </summary>
        /// <param name="partType">部件类型。</param>
        /// <param name="contractName">契约名称。</param>
        /// <param name="part">匹配的插件。</param>
        /// <returns>是否成功获取。</returns>
        bool TryGet(Type partType, string contractName, out object part);

        #endregion "Get"

        /// <summary>
        /// 创造容器。
        /// </summary>
        void CreateContainer();

        /// <summary>
        /// 静态导入。
        /// </summary>
        /// <param name="objectWithLooseImports">松导入的对象。</param>
        void SatisfyImports(params object[] objectWithLooseImports);

        /// <summary>
        ///  约束制造器。
        /// </summary>
        ConventionBuilder ConventionBuilder { get; }
    }
}